﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Crank.Core
{
    public class PreprocessingTokenizer : CalTokenizer
    {
        protected override void Initialize()
        {
            Recognize("^@(.*)$", TokenType.PreprocessorInstruction);
            base.Initialize();
        }

        public PreprocessingTokenizer(ILineProvider source) : base(source) { }

        protected override void LoadNextToken()
        {
            base.LoadNextToken();
            while (CurrentToken.Is(TokenType.PreprocessorInstruction))
            {
                Process(CurrentToken.Text);
                base.LoadNextToken();
            }
        }

        public override Token Eat(TokenType expected)
        {
            foreach (PreProcInstruction PendingInstruction in PendingInstructions)
                PendingInstruction.Process();
            PendingInstructions = new List<PreProcInstruction>();
            return base.Eat(expected);
        }

        private void Process(string line)
        {
            var firstSpaceIndex = line.IndexOf(" ");
            var name = line.Substring(1, firstSpaceIndex - 1).ToUpper();
            var paramstring = line.Substring(firstSpaceIndex + 1);
            PendingInstructions.Add(new PreProcInstruction { Name = name, Args = paramstring.Split(" ".ToCharArray()) });
        }

        private IList<PreProcInstruction> PendingInstructions = new List<PreProcInstruction>();

        private struct PreProcInstruction
        {
            public string Name { get; set; }
            public string[] Args { get; set; }

            internal void Process()
            {
                Preprocessor.Process(Name, Args);
            }
        }

    }
}
